package com.snowfeel.sfmall.core.exception;

import com.snowfeel.sfmall.core.enums.ResponseCode;
import com.snowfeel.sfmall.core.response.JsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.stream.Collectors;

/**
 * @author guomenghuai
 * @date 2024/8/24
 * @Description 全局系统异常处理，调整异常处理的HTTP状态码，丰富异常处理类型
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * RequestBody参数处理
     *
     * @param e
     * @param <T>
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public <T> JsonResult<T> processException(MethodArgumentNotValidException e) {
        LOGGER.error("MethodArgumentNotValidException:{}", e.getMessage());
        String msg = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("；"));
        return JsonResult.error(ResponseCode.ILLEGAL_PARAMETER, msg);
    }

    /**
     * 非法参数处理
     * @param e
     * @return
     * @param <T>
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public <T> JsonResult<T> handleIllegalArgumentException(IllegalArgumentException e) {
        LOGGER.error("非法参数异常，异常原因：{}", e.getMessage(), e);
        return JsonResult.error(ResponseCode.ILLEGAL_PARAMETER);
    }

    /**
     * 业务异常处理
     * @param e
     * @return
     * @param <T>
     */
    @ExceptionHandler(BizException.class)
    public <T> JsonResult<T> handleBizException(BizException e) {
        LOGGER.error("biz exception:{}", e.getMessage(), e);
        if (e.getCode() != null) {
            return JsonResult.error(e.getCode(), e.getMessage());
        }
        return JsonResult.error(e.getMessage());
    }

    /**
     * 未知异常处理
     * @param e
     * @return
     * @param <T>
     */
    @ExceptionHandler(Exception.class)
    public <T> JsonResult<T> handleException(Exception e) {
        LOGGER.error("unknown exception:{}", e.getMessage(), e);
        return JsonResult.error(e.getMessage());
    }

}
